'
' Copyright (c) 2004
' by Peter Donker ( info@bring2mind.net )
'
' Permission is hereby granted to use and/or modify this software for a single server. It is 
' NOT permitted to publish, distribute, sublicense, and/or sell copies of this software in its
' original or modified form. You are not allowed to remove this copyright notice. Please read the
' enclosed EULA for further details.
'
' THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 
' BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
' NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 
' DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
' OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OF THE SOFTWARE.
'
Imports System
Imports System.Web.UI.WebControls
Imports DotNetNuke
Imports DotNetNuke.Services.Localization.Localization
Imports System.Xml

Namespace Bring2mind.DNN.Modules.Questionnaire.Controls

 Public Class Questionnaire
  Inherits Controls.PortalModuleBase
  'Inherits DotNetNuke.Entities.Modules.PortalModuleBase

#Region " Web Form Designer Generated Code "

  'This call is required by the Web Form Designer.
  <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()

  End Sub

  'NOTE: The following placeholder declaration is required by the Web Form Designer.
  'Do not delete or move it.
  Private designerPlaceholderDeclaration As System.Object

#End Region

#Region " Controls "
  Protected WithEvents cmdSubmit As System.Web.UI.WebControls.LinkButton
  Protected WithEvents cmdDelete As System.Web.UI.WebControls.LinkButton
  Protected WithEvents cmdCancel As System.Web.UI.WebControls.LinkButton
  Protected WithEvents plhQuestionnaire As System.Web.UI.WebControls.PlaceHolder
  Protected WithEvents lblRequired As System.Web.UI.WebControls.Label
#End Region

#Region " Private Members "
  Dim _xmlResults As XmlDocument
  Dim _ourQuestionnaire As QuestionnaireTemplate.questionnaireRow
  Dim _resultsFile As String
#End Region

#Region " Event Handlers "
  Private Sub Page_Init(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Init
   'CODEGEN: This method call is required by the Web Form Designer
   'Do not modify it using the code editor.
   InitializeComponent()

   Try
    _ourQuestionnaire = Me.Questionnaire.questionnaire.Rows(0)
    _resultsFile = Me.ModuleSettings.ResultsFile(_ourQuestionnaire, True)
    _xmlResults = New XmlDocument
    If IO.File.Exists(_resultsFile) Then
     _xmlResults.Load(_resultsFile)
    Else
     _xmlResults.AppendChild(_xmlResults.CreateXmlDeclaration("1.0", "UTF-8", "yes"))
     _xmlResults.AppendChild(_xmlResults.CreateElement("responses"))
     _xmlResults.Save(_resultsFile)
    End If
   Catch ex As Exception
   End Try

  End Sub

  Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

   If Me.Questionnaire Is Nothing Then

    Dim dl As New Dialog
    With dl
     .Title = GetString("NoQuestionnaireTitle", Me.LocalResourceFile)
     .Description = GetString("NoQuestionnaireDescription", Me.LocalResourceFile)
    End With
    Me.Controls.Add(dl)

    cmdSubmit.Visible = False
    Exit Sub

   End If

   Try

    Dim ErrorMsg As String = ""
    Dim xmlUserData As XmlNode

    If Not IsPostBack Then

     cmdDelete.Visible = False
     cmdCancel.Visible = Me.ModuleSettings.ResultsPublic
     cmdDelete.Attributes.Add("onClick", "javascript:return confirm('" & Services.Localization.Localization.GetString("DeleteItem") & "');")

     'If Not ModuleSettings.AllowMultiple And UserId > -1 Then
     If UserId > -1 Then

      ' Get the user's data if any
      cmdDelete.Visible = True
      cmdCancel.Visible = True
      Try
       If Me.Query.DetailId <> "" Then
        If Me.Permission = "ADMIN" Then
         xmlUserData = _xmlResults.SelectSingleNode("/responses/response[response_id='" & Me.Query.DetailId & "']")
        Else
         xmlUserData = _xmlResults.SelectSingleNode("/responses/response[response_id='" & Me.Query.DetailId & "' and q_respondent/username='" & Me.UserInfo.Username & "']")
        End If
       Else
        If Not Me.ModuleSettings.AllowMultiple Then
         xmlUserData = _xmlResults.SelectSingleNode("/responses/response[q_respondent/username='" & Me.UserInfo.Username & "']")
        End If
       End If
      Catch ex As Exception
       cmdDelete.Visible = False
      End Try

      If Not Me.ModuleSettings.ResultsPublic Then
       Dim bSubmitted As Boolean, qkey As String
       If _ourQuestionnaire.IsquestionnaireidNull Then
        qkey = "Questionnaire_" & ModuleId.ToString
       Else
        qkey = "Questionnaire_" & _ourQuestionnaire.questionnaireid
       End If
       If Not DotNetNuke.Services.Personalization.Personalization.GetProfile(qkey, "Submitted") Is Nothing Then
        bSubmitted = CType(DotNetNuke.Services.Personalization.Personalization.GetProfile(qkey, "Submitted"), Boolean)
       Else
        bSubmitted = False
       End If
       If (Not ModuleSettings.AllowMultiple And UserId > -1) And bSubmitted Then

        Dim dl As New Dialog
        With dl
         .Title = GetString("AlreadySubmittedTitle", Me.LocalResourceFile)
         .Description = GetString("AlreadySubmittedDescription", Me.LocalResourceFile)
        End With
        Me.Controls.Add(dl)
        cmdSubmit.Visible = False
        Exit Sub

       End If
      End If
     End If
    End If 'postback

    plhQuestionnaire.Controls.Add(GetForm(xmlUserData))

   Catch exc As Exception
    DotNetNuke.Services.Exceptions.ProcessModuleLoadException(Me, exc)
   End Try
  End Sub

  Private Sub Page_PreRender(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.PreRender

   If Not Me.Page.IsClientScriptBlockRegistered("PopCalendar") Then
    Dim sr As New IO.StreamReader(Server.MapPath(Me.TemplateSourceDirectory & "/popcalendar.js"))
    Dim CalScript As String = sr.ReadToEnd
    CalScript = CalScript.Replace("[IMAGEDIRECTORY]", Me.TemplateSourceDirectory & "/")
    sr.Close()
    Page.RegisterClientScriptBlock("PopCalendar", "<script language='javascript'>" & CalScript & "</script>")
   End If

  End Sub

  Private Sub cmdSubmit_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles cmdSubmit.Click

   Dim oldData As XmlNode

   If UserId > -1 Then

    If Me.Query.DetailId <> "" Then
     If Me.Permission = "ADMIN" Then
      oldData = _xmlResults.SelectSingleNode("/responses/response[response_id='" & Me.Query.DetailId & "']")
     Else
      oldData = _xmlResults.SelectSingleNode("/responses/response[response_id='" & Me.Query.DetailId & "' and q_respondent/username='" & Me.UserInfo.Username & "']")
     End If
    Else
     If Not Me.ModuleSettings.AllowMultiple Then
      oldData = _xmlResults.SelectSingleNode("/responses/response[q_respondent/username='" & Me.UserInfo.Username & "']")
     End If
    End If

   End If

   Dim resXml As XmlNode = _xmlResults.CreateElement("response")
   Dim xN As XmlNode
   Dim sbClear As New Text.StringBuilder
   Dim Subject As String
   Dim Attachments As New ArrayList
   Dim OurQuestionnaire As QuestionnaireTemplate.questionnaireRow = Me.Questionnaire.questionnaire.Rows(0)
   Subject = GetString("SubjectPre", Me.LocalResourceFile) & " '" & OurQuestionnaire.title & "'"
   xN = _xmlResults.CreateElement("q_datetime")
   xN.InnerText = Now.ToString("yyyy-MM-dd hh:mm:ss")
   resXml.AppendChild(xN)

   If Not OurQuestionnaire.IsquestionnaireidNull Then
    xN = _xmlResults.CreateElement("questionnaireid")
    xN.InnerText = OurQuestionnaire.questionnaireid
    resXml.AppendChild(xN)
   End If

   If Me.ModuleSettings.SaveResults Then
    xN = _xmlResults.CreateElement("response_id")
    If Me.Query.DetailId <> "" Then
     xN.InnerText = Me.Query.DetailId
    Else
     xN.InnerText = Me.NewId(_xmlResults)
    End If
    resXml.AppendChild(xN)
   End If

   sbClear.Append(Subject & "<br />")

   If (Me.ModuleConfiguration.AuthorizedViewRoles & ";").IndexOf(DotNetNuke.Common.glbRoleAllUsers & ";") < 0 Then
    'Not an anonymous questionnaire
    Dim resp As XmlNode = _xmlResults.CreateElement("q_respondent")
    xN = _xmlResults.CreateElement("name")
    xN.InnerText = UserInfo.FullName
    resp.AppendChild(xN)
    xN = _xmlResults.CreateElement("username")
    xN.InnerText = UserInfo.Username
    resp.AppendChild(xN)
    xN = _xmlResults.CreateElement("email")
    xN.InnerText = UserInfo.Membership.Email
    resp.AppendChild(xN)
    resXml.AppendChild(resp)
   Else
    sbClear.Append("Respondent: " & UserInfo.FullName & " (" & UserInfo.Username & ")" & "<br />")
    sbClear.Append("Email: " & UserInfo.Membership.Email & "<br />")
   End If

   Dim q As QuestionnaireTemplate.questionRow
   Dim iCnt As Integer = 0
   Dim ctrl As Control
   For Each q In Me.Questionnaire.question.Rows
    iCnt += 1

    xN = _xmlResults.CreateElement(q.id)
    sbClear.Append(iCnt.ToString & ". " & q.issue & "<br />")

    ctrl = plhQuestionnaire.FindControl(q.id)
    If ctrl Is Nothing Then
     xN.InnerText = "Control Not Found"
    Else
     Select Case q.type
      Case "String", "Text", "Integer", "Single", "TextBox"
       Dim t As TextBox = CType(ctrl, TextBox)
       xN.InnerXml = DotNetNuke.Common.Utilities.XmlUtils.XMLEncode(t.Text)
       sbClear.Append(t.Text)
      Case "Date"
       Dim t As TextBox = CType(ctrl, TextBox)
       Try
        Dim d As Date = Date.Parse(t.Text)
        xN.InnerXml = d.ToString("u")
        sbClear.Append(t.Text)
       Catch ex As Exception
        xN.InnerXml = ""
        sbClear.Append("")
       End Try
      Case "Html"
       Dim result As String = Me.Request.Params(Me.ClientID & "_" & q.id)
       xN.InnerXml = DotNetNuke.Common.Utilities.XmlUtils.XMLEncode(result)
       sbClear.Append(result)
      Case "Boolean"
       Dim chk As CheckBox = CType(ctrl, CheckBox)
       xN.InnerText = chk.Checked.ToString
       sbClear.Append(chk.Checked.ToString)
      Case "Hidden"
       Dim hid As HtmlInputHidden = CType(ctrl, HtmlInputHidden)
       xN.InnerText = hid.Value
       sbClear.Append(hid.Value)
      Case "SingleOption"
       Dim opts As DropDownList = CType(ctrl, DropDownList)
       xN.InnerText = opts.SelectedValue
       sbClear.Append(opts.SelectedValue)
      Case "MultipleOption"
       Dim opts As CheckBoxList = CType(ctrl, CheckBoxList)
       Dim li As ListItem
       For Each li In opts.Items
        If li.Selected Then
         xN.InnerText &= li.Value & ";"
         sbClear.Append(li.Value & ";")
        End If
       Next
      Case "Grade"
       Dim opts As RadioButtonList = CType(ctrl, RadioButtonList)
       xN.InnerText = opts.SelectedValue
       sbClear.Append(opts.SelectedValue)
      Case "Picture", "File"
       Dim fil As HtmlInputFile = CType(ctrl, HtmlInputFile)
       Dim nf As String = HandlePostedFile(q, fil.PostedFile, oldData)
       xN.InnerText = nf
       sbClear.Append(nf)
       If nf <> "" Then
        Attachments.Add(Me.ModuleSettings.ResultsMapPath & nf)
       End If
     End Select
    End If

    resXml.AppendChild(xN)
    sbClear.Append("<br />" & "<br />")
   Next

   'now either write the results or send them
   If ModuleSettings.SendResults Then

    Dim Resmail As New ResultMail
    Dim _portalSettings As DotNetNuke.Entities.Portals.PortalSettings = CType(HttpContext.Current.Items("PortalSettings"), DotNetNuke.Entities.Portals.PortalSettings)
    With Resmail
     .MailFrom = _portalSettings.Email
     .MailTo = ModuleSettings.DestinationEmail
    End With

    If ModuleSettings.SendAsAttachment Then
     Dim Body As String = "Please find enclosed the questionnaire submitted on " & Now.ToLongDateString & " at " & Now.ToLongTimeString & ". "
     Body &= "This email was sent by the Questionnaire module (ID nr " & ModuleId.ToString & ") in the DNN portal '" & _portalSettings.PortalName & "'. Please contact the web master of this portal by replying to this email if you should not have received this email."
     Dim FileName As String
     If Not OurQuestionnaire.IsquestionnaireidNull Then
      FileName = "Results_" & OurQuestionnaire.questionnaireid & "_" & Now.ToString("yyyyMMdd") & "_" & Now.ToString("hhmmss")
     Else
      FileName = "Results_" & ModuleId.ToString & "_" & Now.ToString("yyyyMMdd") & "_" & Now.ToString("hhmmss")
     End If
     If ModuleSettings.SendAsXml Then
      FileName &= ".xml"
      Dim xmlTmp As New XmlDocument
      Dim xw As New XmlTextWriter(ModuleSettings.UploadMapPath & FileName, System.Text.Encoding.UTF8)
      xw.WriteStartDocument(True)
      If ModuleSettings.ProcessingInstructions <> "" Then
       xw.WriteRaw(ModuleSettings.ProcessingInstructions)
      End If
      'resXml.WriteContentTo(xw)
      xw.WriteRaw(resXml.OuterXml)
      xw.Flush()
      xw.Close()
     Else
      FileName &= ".txt"
      SaveFile(ModuleSettings.UploadMapPath & FileName, sbClear.ToString)
     End If

     Attachments.Add(ModuleSettings.UploadMapPath & FileName)

     With Resmail
      .Attachments = Attachments
      If ModuleSettings.SaveResults Then
       .AttachmentsToDelete.Add(ModuleSettings.UploadMapPath & FileName)
      Else
       .AttachmentsToDelete = Attachments
      End If
      .Subject = Subject
      .Body = Body & vbCrLf & vbCrLf
      .BodyFormat = Mail.MailFormat.Html
     End With
     Resmail.Send()
     'Dim objThread As New System.Threading.Thread(AddressOf Resmail.Send)
     'objThread.Start()

    Else ' Send as inline doc

     If ModuleSettings.SendAsXml Then

      With Resmail
       .Subject = Subject
       .Body = resXml.OuterXml & vbCrLf & vbCrLf
       .BodyFormat = Mail.MailFormat.Text
      End With

     Else

      With Resmail
       .Subject = Subject
       .Body = sbClear.ToString & "<br />" & "<br />"
       .BodyFormat = Mail.MailFormat.Html
      End With

     End If

     With Resmail
      .Attachments = Attachments
      If Not ModuleSettings.SaveResults Then
       .AttachmentsToDelete = Attachments
      End If
     End With
     Dim objThread As New System.Threading.Thread(AddressOf Resmail.Send)
     objThread.Start()

    End If

   End If

   If ModuleSettings.SaveResults Then

    If Not oldData Is Nothing Then
     Try
      _xmlResults.DocumentElement.RemoveChild(oldData)
      _xmlResults.Save(_resultsFile)
     Catch ex As Exception
     End Try
    End If

    _xmlResults.DocumentElement.AppendChild(resXml)
    _xmlResults.Save(_resultsFile)

   End If

   'now mark this user as having submitted and clean up page
   Dim qkey As String
   If OurQuestionnaire.IsquestionnaireidNull Then
    qkey = "Questionnaire_" & ModuleId.ToString
   Else
    qkey = "Questionnaire_" & OurQuestionnaire.questionnaireid
   End If
   Try
    DotNetNuke.Services.Personalization.Personalization.SetProfile(qkey, "Submitted", True)
   Catch ex As Exception
   End Try
   plhQuestionnaire.Visible = False
   cmdSubmit.Visible = False

   If Me.ModuleSettings.ResultsPublic Then
    Response.Redirect(DotNetNuke.Common.NavigateURL)
   Else
    Dim dl As New Dialog, al As New ArrayList
    With dl
     If OurQuestionnaire.IsthankyoutitleNull Or OurQuestionnaire.IsthankyoubodyNull Then
      .Title = GetString("ThanksTitle", Me.LocalResourceFile)
      .Description = GetString("ThanksDescription", Me.LocalResourceFile)
      al.Add(New ListItem(GetString("OK", Me.LocalResourceFile), Common.NavigateURL))
      .Buttons = al
     Else
      .Title = OurQuestionnaire.thankyoutitle
      .Description = OurQuestionnaire.thankyoubody
      If OurQuestionnaire.IsthankyoubuttonNull Then
       al.Add(New ListItem(GetString("OK", Me.LocalResourceFile), Common.NavigateURL))
      Else
       al.Add(New ListItem(OurQuestionnaire.thankyoubutton, Common.NavigateURL))
      End If
      .Buttons = al
     End If
    End With
    Me.Controls.Clear()
    Me.Controls.Add(dl)
   End If

  End Sub

  Private Sub cmdDelete_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles cmdDelete.Click

   If UserId > -1 Then
    Try

     Dim oldData As XmlNode
     If Me.Query.DetailId <> "" Then
      If Me.Permission = "ADMIN" Then
       oldData = _xmlResults.SelectSingleNode("/responses/response[response_id='" & Me.Query.DetailId & "']")
      Else
       oldData = _xmlResults.SelectSingleNode("/responses/response[response_id='" & Me.Query.DetailId & "' and q_respondent/username='" & Me.UserInfo.Username & "']")
      End If
     Else
      If Not Me.ModuleSettings.AllowMultiple Then
       oldData = _xmlResults.SelectSingleNode("/responses/response[q_respondent/username='" & Me.UserInfo.Username & "']")
      End If
     End If

     Dim q As QuestionnaireTemplate.questionRow
     For Each q In Me.Questionnaire.question.Rows
      Select Case q.type
       Case "Picture"
        Try
         If oldData.SelectSingleNode(q.id).InnerText <> "" Then
          IO.File.Delete(Me.ModuleSettings.ResultsMapPath & oldData.SelectSingleNode(q.id).InnerText)
         End If
        Catch ex As Exception
        End Try
      End Select
     Next

     If Not oldData Is Nothing Then
      Try
       _xmlResults.DocumentElement.RemoveChild(oldData)
       _xmlResults.Save(_resultsFile)
      Catch ex As Exception
      End Try
     End If
     Response.Redirect(DotNetNuke.Common.NavigateURL)
    Catch ex As Exception
    End Try
   End If

  End Sub

  Private Sub cmdCancel_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles cmdCancel.Click

   Response.Redirect(DotNetNuke.Common.NavigateURL)

  End Sub
#End Region

#Region " Private Methods "
  Private Function HandlePostedFile(ByRef q As QuestionnaireTemplate.questionRow, ByVal File As HttpPostedFile, ByVal oldData As XmlNode) As String

   If File.ContentLength = 0 Then
    If oldData Is Nothing Then
     Return ""
    Else
     Return oldData.SelectSingleNode(q.id).InnerText
    End If
   Else ' A file has been posted
    If Not oldData Is Nothing Then
     Try
      If oldData.SelectSingleNode(q.id).InnerText <> "" Then
       IO.File.Delete(Me.ModuleSettings.ResultsMapPath & oldData.SelectSingleNode(q.id).InnerText)
      End If
     Catch ex As Exception
     End Try
    End If
   End If

   Dim ext As String = IO.Path.GetExtension(File.FileName)
   Dim i As Integer = 0
   Dim NewFile As String
   If Globals.GetAString(q.mintext) = "" Then
    NewFile = "File_" & Format(Now, "yyyyMMddhhmmss") & "_"
    Do While IO.File.Exists(Me.ModuleSettings.ResultsMapPath & NewFile & i.ToString & ext)
     i += 1
     If i > 100 Then Throw New Exception("Disk full?")
    Loop
    NewFile = "File_" & Format(Now, "yyyyMMddhhmmss") & "_" & i.ToString & ext
   ElseIf q.mintext.ToLower.IndexOf("username") > -1 Then
    NewFile = Me.UserInfo.Username & ext
   ElseIf q.mintext.ToLower.IndexOf("original") > -1 Or q.mintext.ToLower.IndexOf("originalfilename") > -1 Then
    NewFile = IO.Path.GetFileName(File.FileName)
   Else
    NewFile = q.mintext & ext
   End If

   'If PermittedFileExtensions.IndexOf(ext.ToLower & ";") > -1 Then
   File.SaveAs(Me.ModuleSettings.ResultsMapPath & NewFile)
   'Try
   If q.type = "Picture" AndAlso Not q.IssizeNull AndAlso q.size <> 0 Then
    Globals.ResizeImage(Me.ModuleSettings.ResultsMapPath & NewFile, q.size)
   End If
   'Catch ex As Exception
   ' IO.File.Delete(Me.ModuleSettings.ResultsMapPath & NewFile)
   ' NewFile = ""
   'End Try
   'End If

   Return NewFile

  End Function

  Private Function GetForm(ByRef UserData As XmlNode) As Table

   Dim ShowRequired As Boolean = False
   Dim MainTable As New Table, MainRow As TableRow, MainCell As TableCell, txt As HtmlGenericControl

   With MainTable
    .EnableViewState = True
    .CssClass = "Q_Question"
   End With
   MainTable.Rows.Add(MakeRow(_ourQuestionnaire.title, "Q_Title"))
   MainTable.Rows.Add(MakeRow(_ourQuestionnaire.introduction, "Q_Intro"))

   Dim q As QuestionnaireTemplate.questionRow
   Dim iCnt As Integer = 0
   For Each q In Me.Questionnaire.question.Rows
    iCnt += 1
    MainTable.Rows.Add(MakeRow(iCnt.ToString & ". " & q.issue, "Q_Question"))

    MainRow = New TableRow
    MainRow.Cells.Add(MakeCell(q.description, "Q_Description"))

    MainCell = New TableCell
    With MainCell
     .CssClass = "Q_Value"
    End With

    'here we go: now compile the interface
    Select Case q.type

     Case "String", "Text"

      Dim t As New TextBox
      With t
       .ID = q.id
       .CssClass = "Q_Value"
       If q.IssizeNull Then
        .TextMode = TextBoxMode.MultiLine
        .Rows = 7
        .Columns = 60
        .Wrap = True
       Else
        .MaxLength = q.size
        Select Case q.size
         Case Is < 11
          .Columns = 10
         Case Is < 51
          .Columns = 30
         Case Else
          .Columns = 60
        End Select
       End If
       If Not Me.IsPostBack Then
        .Text = GetCellValue(q, UserData)
       End If
       .EnableViewState = True
      End With
      MainCell.Controls.Add(t)
      If q.required Then
       MainCell.Controls.Add(New LiteralControl("&nbsp;*&nbsp;"))
       ShowRequired = True
       Dim r As New RequiredFieldValidator
       With r
        .ControlToValidate = q.id
        .Text = GetString("Required.Text", Me.LocalResourceFile)
        .Display = ValidatorDisplay.Dynamic
       End With
       MainCell.Controls.Add(r)
      End If

     Case "TextBox"

      Dim t As New TextBox
      With t
       .ID = q.id
       .CssClass = "Q_Value"
       .TextMode = TextBoxMode.MultiLine
       .Rows = 7
       .Columns = 60
       .Wrap = True
       If Not Me.IsPostBack Then
        .Text = CType(GetCellValue(q, UserData), String)
       End If
       .EnableViewState = True
      End With
      MainCell.Controls.Add(t)

     Case "Html"

      ' This doesn't work yet.
      'Dim t As DotNetNuke.UI.UserControls.TextEditor = CType(Me.LoadControl(IO.Path.Combine(DotNetNuke.Common.ApplicationPath, "controls/TextEditor.ascx")), DotNetNuke.UI.UserControls.TextEditor)
      Dim t As DotNetNuke.Modules.HTMLEditorProvider.HtmlEditorProvider = DotNetNuke.Modules.HTMLEditorProvider.HtmlEditorProvider.Instance
      t.ControlID = q.id
      t.Initialize()
      With t
       .ID = q.id
       '.CssClass = "Q_Value"
       .Width = Unit.Pixel(500)
       .Height = Unit.Pixel(400)
       If Not Me.IsPostBack Then
        '.Text = System.Web.HttpUtility.HtmlEncode(GetCellValue(q, UserData))
        .Text = GetCellValue(q, UserData)
       End If
       .EnableViewState = True
      End With
      MainCell.Controls.Add(t.HtmlEditorControl)

     Case "Integer", "Single"

      Dim t As New TextBox
      With t
       .ID = q.id
       .CssClass = "Q_Value"
       .MaxLength = 10
       .Columns = 10
       If Not Me.IsPostBack Then
        .Text = GetCellValue(q, UserData)
       End If
       .EnableViewState = True
      End With
      MainCell.Controls.Add(t)
      MainCell.Controls.Add(New LiteralControl("&nbsp;"))
      Dim n As New CompareValidator
      With n
       .CssClass = "NormalRed"
       .Display = ValidatorDisplay.Dynamic
       .ErrorMessage = "Not a valid number"
       .[Operator] = ValidationCompareOperator.DataTypeCheck
       .ControlToValidate = q.id
       If q.type = "Integer" Then
        .Type = ValidationDataType.Integer
       Else
        .Type = ValidationDataType.Double
       End If
      End With
      MainCell.Controls.Add(n)
      If q.required Then
       MainCell.Controls.Add(New LiteralControl("&nbsp;*&nbsp;"))
       ShowRequired = True
       Dim r As New RequiredFieldValidator
       With r
        .ControlToValidate = q.id
        .Text = GetString("Required.Text", Me.LocalResourceFile)
        .Display = ValidatorDisplay.Dynamic
       End With
       MainCell.Controls.Add(r)
      End If

     Case "Date"

      Dim t As New TextBox
      With t
       .ID = q.id
       .CssClass = "Q_Value"
       .MaxLength = 10
       .Columns = 10
       If Not Me.IsPostBack Then
        Try
         .Text = Date.Parse(GetCellValue(q, UserData)).ToString("d")
        Catch ex As Exception
        End Try
       End If
       .EnableViewState = True
      End With
      MainCell.Controls.Add(t)
      MainCell.Controls.Add(New LiteralControl("&nbsp;"))
      Dim img As New Image
      With img
       .ID = "Image_" & q.id
       .ImageUrl = Me.TemplateSourceDirectory & "/ew_calendar.gif"
       .Attributes.Add("style", "cursor: hand")
       .Attributes.Add("onclick", "popUpCalendar(this, this.previousSibling.previousSibling, '" & System.Globalization.CultureInfo.CurrentCulture.DateTimeFormat.ShortDatePattern & "');return false;")
      End With
      MainCell.Controls.Add(img)
      Dim n As New CompareValidator
      With n
       .CssClass = "NormalRed"
       .Display = ValidatorDisplay.Dynamic
       .ErrorMessage = "Not a valid date"
       .[Operator] = ValidationCompareOperator.DataTypeCheck
       .ControlToValidate = q.id
       .Type = ValidationDataType.Date
      End With
      MainCell.Controls.Add(n)
      If q.required Then
       MainCell.Controls.Add(New LiteralControl("&nbsp;*&nbsp;"))
       ShowRequired = True
       Dim r As New RequiredFieldValidator
       With r
        .ControlToValidate = q.id
        .Text = GetString("Required.Text", Me.LocalResourceFile)
        .Display = ValidatorDisplay.Dynamic
       End With
       MainCell.Controls.Add(r)
      End If

     Case "SingleOption"

      Dim opts As New DropDownList
      With opts
       .ID = q.id
       .CssClass = "Q_Value"
       .DataValueField = "value"
       .DataTextField = "text"
       .DataSource = q.GetoptionsRows(0).GetoptionRows
       .DataBind()
      End With
      Dim crtval As String = GetCellValue(q, UserData)
      If Not opts.Items.FindByValue(crtval) Is Nothing Then
       opts.Items.FindByValue(crtval).Selected = True
      End If
      MainCell.Controls.Add(opts)

     Case "MultipleOption"

      Dim opts As New CheckBoxList
      With opts
       .ID = q.id
       .CssClass = "Q_Value"
       .DataValueField = "value"
       .DataTextField = "text"
       Try
        .RepeatColumns = q.size
       Catch ex As Exception
       End Try
       .DataSource = q.GetoptionsRows(0).GetoptionRows
       .DataBind()
      End With
      Dim crtval As String = GetCellValue(q, UserData)
      Dim val As String
      For Each val In crtval.Split(New Char() {";"})
       If Not opts.Items.FindByValue(val) Is Nothing Then
        opts.Items.FindByValue(val).Selected = True
       End If
      Next
      MainCell.Controls.Add(opts)

     Case "Boolean"

      Dim chk As New CheckBox
      With chk
       .ID = q.id
       .CssClass = "Q_Value"
       Try
        .Checked = Boolean.Parse(GetCellValue(q, UserData))
       Catch ex As Exception
       End Try
      End With
      MainCell.Controls.Add(chk)

     Case "Hidden"

      Dim hid As New HtmlInputHidden
      With hid
       .ID = q.id
       .Value = GetCellValue(q, UserData)
      End With
      MainCell.Controls.Add(hid)

     Case "Grade"

      If Not (q.IssizeNull Or q.IsmintextNull Or q.IsmaxtextNull) Then
       Dim tb As New Table
       Dim tr As New TableRow
       Dim tc As New TableCell
       With tc
        .Style.Add("text-align", "left")
        .Controls.Add(New LiteralControl(q.mintext))
        .CssClass = "Q_Value"
       End With
       tr.Cells.Add(tc)
       tc = New TableCell
       With tc
        .Style.Add("text-align", "right")
        .Controls.Add(New LiteralControl(q.maxtext))
        .CssClass = "Q_Value"
       End With
       tr.Cells.Add(tc)
       tb.Rows.Add(tr)
       tr = New TableRow
       tc = New TableCell
       Dim iVals(q.size - 1) As Integer
       Dim i As Integer
       For i = 1 To q.size
        iVals(i - 1) = i
       Next
       Dim opts As New RadioButtonList
       With opts
        .ID = q.id
        .CssClass = "Q_Value"
        .DataSource = iVals
        .DataBind()
        .RepeatColumns = q.size
        .RepeatDirection = RepeatDirection.Horizontal
        .DataTextFormatString = ""
        Try
         .Items.FindByValue(GetCellValue(q, UserData)).Selected = True
        Catch ex As Exception
        End Try
       End With
       With tc
        .ColumnSpan = 2
        .Controls.Add(opts)
       End With
       tr.Cells.Add(tc)
       tb.Rows.Add(tr)
       MainCell.Controls.Add(tb)
       If q.required Then
        MainCell.Controls.Add(New LiteralControl("&nbsp;*&nbsp;"))
        ShowRequired = True
        Dim r As New RequiredFieldValidator
        With r
         .ControlToValidate = q.id
         .Text = GetString("Required.Text", Me.LocalResourceFile)
         .Display = ValidatorDisplay.Dynamic
        End With
        MainCell.Controls.Add(r)
       End If

      End If

     Case "Picture", "File"

      Dim p As New HtmlInputFile
      p.ID = q.id
      MainCell.Controls.Add(p)
      Dim fil As String = GetCellValue(q, UserData)
      If q.type = "Picture" AndAlso fil <> "" AndAlso IO.File.Exists(Me.ModuleSettings.ResultsMapPath & fil) Then
       MainCell.Controls.Add(New LiteralControl("<br/>"))
       Dim img As New Image
       img.ImageUrl = Me.ModuleSettings.ResultsPath & fil
       'img.ImageAlign = ImageAlign.TextTop
       MainCell.Controls.Add(img)
      Else
       If q.required Then
        MainCell.Controls.Add(New LiteralControl("&nbsp;*&nbsp;"))
        ShowRequired = True
        Dim r As New RequiredFieldValidator
        With r
         .ControlToValidate = q.id
         .Text = GetString("Required.Text", Me.LocalResourceFile)
         .Display = ValidatorDisplay.Dynamic
        End With
        MainCell.Controls.Add(r)
        ShowRequired = True
       End If
      End If
      If Not q.Is_defaultNull AndAlso q._default <> "" Then
       MainCell.Controls.Add(New LiteralControl("&nbsp;(" & q._default & ")&nbsp;"))
       Dim exts As String = q._default.Trim(New Char() {";"c, " "c})
       Dim expr As String = ""
       For i As Integer = 1 To Len(exts)
        If Mid(exts, i, 1) = "*" Then
         expr &= ".+"
        ElseIf Mid(exts, i, 1) = "." Then
         expr &= "\."
        ElseIf Mid(exts, i, 1) = ";" Then
         expr &= "$)|("
        Else
         expr &= "[" & Mid(exts, i, 1).ToLower & Mid(exts, i, 1).ToUpper & "]"
        End If
       Next
       expr = "(" & expr & "$)"
       Dim rev As New RegularExpressionValidator
       With rev
        '.ValidationExpression = ".+\.zip$"
        .ValidationExpression = expr
        .ControlToValidate = q.id
        .Text = GetString("Invalid.Text", Me.LocalResourceFile)
        .Display = ValidatorDisplay.Dynamic
       End With
       MainCell.Controls.Add(rev)
      End If

     Case Else

      MainCell.Controls.Add(New LiteralControl("Data Type '" & q.type & "' not recognized"))

    End Select
    MainRow.Cells.Add(MainCell)

    MainTable.Rows.Add(MainRow)
   Next

   If ShowRequired Then
    lblRequired.Visible = ShowRequired
    lblRequired.Text = "*&nbsp;" & GetString("RequiredFields.Text", Me.LocalResourceFile)
   End If

   Return MainTable

  End Function

  Private Function GetCellValue(ByVal q As QuestionnaireTemplate.questionRow, ByVal UserData As XmlNode) As Object
   If UserData Is Nothing Then ' No prior data
    If Not Me.Request.Params(q.id) Is Nothing Then ' We have something in the querystring
     Return Me.Request.Params(q.id)
    End If
    If Not q.Is_defaultNull Then ' We have a default value
     If q._default.ToLower.StartsWith("user.") Then
      Try
       Return DataBinder.Eval(UserInfo, Mid(q._default, 6))
      Catch ex As Exception
       Return q._default
      End Try
     ElseIf q._default.ToLower.StartsWith("profile.") Then
      Try
       Return DataBinder.Eval(UserInfo.Profile, Mid(q._default, 9))
      Catch ex As Exception
       Return q._default
      End Try
     ElseIf q._default.ToLower.StartsWith("membership.") And q._default.ToLower.IndexOf("password") < 0 Then
      Try
       Return DataBinder.Eval(UserInfo.Membership, Mid(q._default, 12))
      Catch ex As Exception
       Return q._default
      End Try
     ElseIf InStr(q._default.ToLower, "now") = 1 Then
      Return Now.ToShortDateString
     Else
      Return q._default
     End If
    Else ' We don't have a default value, this will return Null
     Return q._default
    End If
   Else ' We have previous data
    Try
     Return UserData.SelectSingleNode(q.id).InnerText
    Catch ex As Exception
     Return q._default
    End Try
   End If
  End Function

  Private Function MakeCell(ByVal Text As String, ByVal CssClass As String, Optional ByVal ColSpan As Integer = 1) As TableCell
   Dim tc As New TableCell
   With tc
    .Text = Text
    .CssClass = CssClass
    .ColumnSpan = ColSpan
   End With
   Return tc
  End Function

  Private Function MakeRow(ByVal Text As String, ByVal CssClass As String) As TableRow
   Dim tr As New TableRow
   tr.Cells.Add(MakeCell(Text, CssClass, 2))
   Return tr
  End Function
#End Region

 End Class

End Namespace
